#include "pagridplot.h"

static int scan_choice(int *c);

int labels_log(menu_labels* labels){
  strcpy(labels->before_ini,"before initial partitioning");
  strcpy(labels->after_ini,"after initial partitioning");
  strcpy(labels->percent,"percent");
  strcpy(labels->distrib,"plot distribution");
  strcpy(labels->xy,"plot xy graph");
  strcpy(labels->xyz,"plot 3d graph");

  strcpy(labels->ext[STDOUT],"stdout");
  strcpy(labels->ext[PNG],"png");
  strcpy(labels->ext[PS],"ps");
  strcpy(labels->ext[EPS],"eps");
  strcpy(labels->ext[PDF],"pdf");

  strcpy(labels->label[LOG_CUTEDGE], "Cut Edge Weight");
  strcpy(labels->label[LOG_TOTCOMMCOST], "Total Communication Cost");
  strcpy(labels->label[LOG_MAXWEIGHT], "Maximum Processor Weight");
  strcpy(labels->label[LOG_CUTEDGEBYTOTCOMMCOST], "Cut Edge Weight / Total Communication Cost");
  strcpy(labels->label[LOG_IMBALANCE], "Imbalance Factor");
  strcpy(labels->label[LOG_MAXEXECTIME], "Maximum Execution Time");
  strcpy(labels->label[11],"matching min degree");
  strcpy(labels->label[12],"matching max degree");
  strcpy(labels->label[13],"matching average degree");
  strcpy(labels->label[14],"matching standard deviation of degrees");
  strcpy(labels->label[15],"matching sum of degrees");
  strcpy(labels->label[21],"matching min vertex weight");
  strcpy(labels->label[22],"matching max vertex weight");
  strcpy(labels->label[23],"matching average vertex weight");
  strcpy(labels->label[24],"matching standard deviation of vertex weights");
  strcpy(labels->label[25],"matching sum of vertex weights");
  strcpy(labels->label[31],"matching min cut edge");
  strcpy(labels->label[32],"matching max cut edge");
  strcpy(labels->label[33],"matching average cut edge");
  strcpy(labels->label[34],"matching standard deviation of cut edges");
  strcpy(labels->label[35],"matching sum of cut edges");
  strcpy(labels->label[40],"matching imbalance factor");
  strcpy(labels->label[71],"matching min edge weight");
  strcpy(labels->label[72],"matching max edge weight");
  strcpy(labels->label[73],"matching average edge weight");
  strcpy(labels->label[74],"matching standard deviation of edge weights");
  strcpy(labels->label[75],"matching sum of edge weights");

  strcpy(labels->file[LOG_CUTEDGE], ".cut");
  strcpy(labels->file[LOG_TOTCOMMCOST], ".comm");
  strcpy(labels->file[LOG_MAXWEIGHT], ".maxw");
  strcpy(labels->file[LOG_CUTEDGEBYTOTCOMMCOST], ".cutbycomm");
  strcpy(labels->file[LOG_IMBALANCE], ".im");
  strcpy(labels->file[LOG_MAXEXECTIME], ".maxex");
  strcpy(labels->file[11],".mind");
  strcpy(labels->file[12],".maxd");
  strcpy(labels->file[13],".avgd");
  strcpy(labels->file[14],".stdevd");
  strcpy(labels->file[15],".sumd");
  strcpy(labels->file[21],".minw");
  strcpy(labels->file[22],".maxw");
  strcpy(labels->file[23],".avgw");
  strcpy(labels->file[24],".stdevw");
  strcpy(labels->file[25],".sumw");
  strcpy(labels->file[31],".minc");
  strcpy(labels->file[32],".maxc");
  strcpy(labels->file[33],".avgc");
  strcpy(labels->file[34],".stdevc");
  strcpy(labels->file[35],".sumc");
  strcpy(labels->file[40],".imb");
  strcpy(labels->file[71],".minew");
  strcpy(labels->file[72],".maxew");
  strcpy(labels->file[73],".avgew");
  strcpy(labels->file[74],".stdevew");
  strcpy(labels->file[75],".sumew");

  /* filenames */
  strcpy(labels->F_stdout,"stdout");
  strcpy(labels->F_stats,".stat.log");
  strcpy(labels->F_plot,"stdout");

  return 1;
}

int scan_choice(int *c){
  int result = 1;
  if(scanf("%d",c) != 1)
    result = 0;
  else
    getchar();
  return result;
}

int main_menu(MENU_FN* menu_fct,menu_info* info){
  int option = -1;
  int coords;

  WARNING((info->info1 == NULL,"main_menu error 1 : info->info1 undefined\n"),0);
  coords = *((int*)info->info1);

  do{
    info->option = option;
    (*menu_fct)(info);
    
    printf("-------------------------------------------------\n");
    printf("| %45s |\n","Choose log file");
    printf("-------------------------------------------------\n");
    printf("| %2d | %40s |\n",1,"Timing");
    printf("| %2d | %40s |\n",2,"Before execution time load balancing");
    printf("| %2d | %40s |\n",3,"After execution time load balancing");
    printf("-------------------------------------------------\n");
    printf("| %45s |\n","Matching information");
    printf("-------------------------------------------------\n");
    printf("| %2d | %40s |\n",4,"Stats");
    if(coords)
      printf("| %2d | %40s |\n",5,"Generate OpenDx files for matchings");
    printf("-------------------------------------------------\n");
    printf("| %45s |\n","Refinement information");
    printf("-------------------------------------------------\n");
    printf("| %2d | %40s |\n",6,"Stats");
    if(coords)
      printf("| %2d | %40s |\n",7,"Generate OpenDx files for refinement");
    if(coords){
      printf("-------------------------------------------------\n");
      printf("| %45s |\n","Geomview");
      printf("-------------------------------------------------\n");
      printf("| %2d | %40s |\n",8,"Application graph");
      printf("| %2d | %40s |\n",9,"Final partition");
    }
    printf("-------------------------------------------------\n");
    printf("| %2d | %40s |\n",10,"Quit");
    printf("-------------------------------------------------\n");
    printf("choice : ");
  }while(scan_choice(&option) && option != 10);

  return 1;
}

int values_menu(MENU_FN* menu_fct,menu_info* info){
  int option = -1;
  int* val;
  logFctrl* ctrl;

  WARNING((info->info1 == NULL,"values_menu error 1 : info->info1 undefined\n"),0);
  WARNING((info->info2 == NULL,"values_menu error 2 : info->info2 undefined\n"),0);
  ctrl = (logFctrl*)info->info1;
  val = (int*)info->info2;

  do{
    info->option = option;
    (*menu_fct)(info);
    printf("-----------------------------------------------------------------------------------\n");
    if(val == &(ctrl->x)){
      printf("| %79s |\n","X values");
    }else if(val == &(ctrl->y)){
      printf("| %79s |\n","Y values");
    }else{
      printf("| %79s |\n","Y values");
    }
    printf("-----------------------------------------------------------------------------------\n");
    printf("| %c | %2d | %70s |\n",(*val == LOG_CUTEDGE?'*':' '),LOG_CUTEDGE,
	   ctrl->labels->label[LOG_CUTEDGE]);
    printf("| %c | %2d | %70s |\n",(*val == LOG_TOTCOMMCOST?'*':' '),LOG_TOTCOMMCOST,
	   ctrl->labels->label[LOG_TOTCOMMCOST]);
    printf("| %c | %2d | %70s |\n",(*val == LOG_MAXWEIGHT?'*':' '),LOG_MAXWEIGHT,
	   ctrl->labels->label[LOG_MAXWEIGHT]);
    printf("| %c | %2d | %70s |\n",(*val == LOG_CUTEDGEBYTOTCOMMCOST?'*':' '),LOG_CUTEDGEBYTOTCOMMCOST,
	   ctrl->labels->label[LOG_CUTEDGEBYTOTCOMMCOST]);
    printf("| %c | %2d | %70s |\n",(*val == LOG_IMBALANCE?'*':' '),LOG_IMBALANCE,
	   ctrl->labels->label[LOG_IMBALANCE]);
    printf("| %c | %2d | %70s |\n",(*val == LOG_MAXEXECTIME?'*':' '),LOG_MAXEXECTIME,
	   ctrl->labels->label[LOG_MAXEXECTIME]);
    if(((val == &(ctrl->x)) || (val == &(ctrl->y) && ctrl->plotstyle == ctrl->labels->xyz)) && 
       ctrl->group == BY_COARSENING){
      printf("-----------------------------------------------------------------------------------\n");
      printf("| %79s |\n","Coarsest Graph");
      printf("-----------------------------------------------------------------------------------\n");
      printf("| %c | %2d | %36s%18s %15s |\n",(*val == 11?'*':' '),11,"","min","degree");
      printf("| %c | %2d | %36s%18s %15s |\n",(*val == 12?'*':' '),12,"","max","");
      printf("| %c | %2d | %36s%18s %15s |\n",(*val == 13?'*':' '),13,"","average","");
      printf("| %c | %2d | %36s%18s %15s |\n",(*val == 14?'*':' '),14,"","standard deviation","");
      printf("| %c | %2d | %36s%18s %15s |\n",(*val == 15?'*':' '),15,"","sum","");
      printf("| %c | %2d | %36s%18s %15s |\n",(*val == 21?'*':' '),21,"","min","vertex weight");
      printf("| %c | %2d | %36s%18s %15s |\n",(*val == 22?'*':' '),22,"","max","");
      printf("| %c | %2d | %36s%18s %15s |\n",(*val == 23?'*':' '),23,"","average","");
      printf("| %c | %2d | %36s%18s %15s |\n",(*val == 24?'*':' '),24,"","standard deviation","");
      printf("| %c | %2d | %36s%18s %15s |\n",(*val == 25?'*':' '),25,"","sum","");
      printf("| %c | %2d | %36s%18s %15s |\n",(*val == 31?'*':' '),31,"","min","cut edge");
      printf("| %c | %2d | %36s%18s %15s |\n",(*val == 32?'*':' '),32,"","max","");
      printf("| %c | %2d | %36s%18s %15s |\n",(*val == 33?'*':' '),33,"","average","");
      printf("| %c | %2d | %36s%18s %15s |\n",(*val == 34?'*':' '),34,"","standard deviation","");
      printf("| %c | %2d | %36s%18s %15s |\n",(*val == 35?'*':' '),35,"","sum","");
      if(ctrl->part == ctrl->labels->after_ini)
	printf("| %c | %2d | %36s%8s %25s |\n",(*val == 40?'*':' '),40,"","","imbalance factor");
      printf("| %c | %2d | %36s%18s %15s |\n",(*val == 71?'*':' '),71,"","min","edge weight");
      printf("| %c | %2d | %36s%18s %15s |\n",(*val == 72?'*':' '),72,"","max","");
      printf("| %c | %2d | %36s%18s %15s |\n",(*val == 73?'*':' '),73,"","average","");
      printf("| %c | %2d | %36s%18s %15s |\n",(*val == 74?'*':' '),74,"","standard deviation","");
      printf("| %c | %2d | %36s%18s %15s |\n",(*val == 75?'*':' '),75,"","sum","");
    }
    printf("-----------------------------------------------------------------------------------\n");
    printf("|   | 99 | %70s |\n","back");
    printf("-----------------------------------------------------------------------------------\n");
    printf("choice : ");
  }while(scan_choice(&option) && option != 99);
  return 1;
}

int group_menu(MENU_FN* menu_fct,menu_info* info){
  int option = -1;
  logFctrl* ctrl;

  WARNING((info->info1 == NULL,"group_menu error 1 : info->info1 undefined\n"),0);
  ctrl = (logFctrl*)info->info1;

  do{
    info->option = option;
    (*menu_fct)(info);
    printf("---------------------------------\n");
    printf("|   | %25s |\n","Grouping method");
    printf("---------------------------------\n");
    printf("| %c | %2d | %20s |\n",(ctrl->group==BY_MATCHING?'*':' '),BY_MATCHING,"by matching file");
    printf("| %c | %2d | %20s |\n",(ctrl->group==BY_COARSENING?'*':' '),BY_COARSENING,"by coarsening method");
    printf("---------------------------------\n");
    printf("|   | %2d | %20s |\n",BY_COARSENING+1,"back");
    printf("---------------------------------\n");
    printf("choice : ");    
  }while(scan_choice(&option) && option != BY_COARSENING+1);
  return 1;
}

int part_menu(MENU_FN* menu_fct,menu_info* info){
  int option = -1;
  logFctrl* ctrl;

  WARNING((info->info1 == NULL,"part_menu error 1 : info->info1 undefined\n"),0);
  ctrl = (logFctrl*)info->info1;

  do{
    info->option = option;
    (*menu_fct)(info);
    printf("-----------------------------------------------------------------------------------\n");
    printf("|   | %75s |\n","Partition");
    printf("-----------------------------------------------------------------------------------\n");
    printf("| %c | %2d | %70s |\n",(ctrl->part==ctrl->labels->before_ini?'*':' '),1,ctrl->labels->before_ini);
    printf("| %c | %2d | %70s |\n",(ctrl->part==ctrl->labels->after_ini?'*':' '),2,ctrl->labels->after_ini);
    printf("-----------------------------------------------------------------------------------\n");
    printf("|   | %2d | %70s |\n",3,"back");
    printf("-----------------------------------------------------------------------------------\n");
    printf("choice : ");
  }while(scan_choice(&option) && option != 3);
  return 1;
}

int plot_ext_menu(MENU_FN* menu_fct,menu_info* info){
  int option = -1;
  logFctrl* ctrl;

  WARNING((info->info1 == NULL,"plot_ext_menu error 1 : info->info1 undefined\n"),0);
  ctrl = (logFctrl*)info->info1;

  do{
    info->option = option;
    (*menu_fct)(info);
    printf("-----------------------\n");
    printf("|   | %15s |\n","Plots output");
    printf("-----------------------\n");
    printf("| %c | %2d | %10s |\n",(ctrl->plot_ext == STDOUT?'*':' '),STDOUT,ctrl->labels->F_stdout);
    printf("| %c | %2d | %10s |\n",(ctrl->plot_ext == PNG?'*':' '),PNG,"PNG");
    printf("| %c | %2d | %10s |\n",(ctrl->plot_ext == PS?'*':' '),PS,"PS");
    printf("| %c | %2d | %10s |\n",(ctrl->plot_ext == EPS?'*':' '),EPS,"EPS");
    printf("| %c | %2d | %10s |\n",(ctrl->plot_ext == PDF?'*':' '),PDF,"PDF");
    printf("-----------------------\n");
    printf("| %c | %2d | %10s |\n",' ',PDF+1,"back");
    printf("-----------------------\n");
    printf("choice : ");
  }while(scan_choice(&option) && option != PDF+1);
  return 1;
}

int F_stat_menu(MENU_FN* menu_fct,menu_info* info){
  int option = -1;
  logFctrl* ctrl;

  WARNING((info->info1 == NULL,"F_stat_menu error 1 : info->info1 undefined\n"),0);
  ctrl = (logFctrl*)info->info1;

  do{
    info->option = option;
    (*menu_fct)(info);

    printf("-----------------------------------------------------------------------------------\n");
    printf("|   | %75s |\n","Statistics output");
    printf("-----------------------------------------------------------------------------------\n");
    printf("| %c | %2d | %70s |\n",(ctrl->F_stats == ctrl->labels->F_stdout?'*':' '),1,ctrl->labels->F_stdout);
    printf("| %c | %2d | %70s |\n",(ctrl->F_stats == ctrl->labels->F_stats?'*':' '),2,ctrl->labels->F_stats);
    printf("-----------------------------------------------------------------------------------\n");
    printf("| %c | %2d | %70s |\n",' ',3,"back");    
    printf("-----------------------------------------------------------------------------------\n");    
    printf("choice : ");
  }while(scan_choice(&option) && option != 3);
  return 1;
}

int plotstyle_menu(MENU_FN* menu_fct,menu_info* info){
  int option = -1;
  logFctrl* ctrl;

  WARNING((info->info1 == NULL,"plotstyle_menu error 1 : info->info1 undefined\n"),0);
  ctrl = (logFctrl*)info->info1;

  do{
    info->option = option;
    (*menu_fct)(info);
    printf("-----------------------------------------------------------------------------------\n");
    printf("|   | %75s |\n","Plot Style");
    printf("-----------------------------------------------------------------------------------\n");
    printf("| %c | %2d | %70s |\n",(ctrl->plotstyle == ctrl->labels->distrib?'*':' '),1,ctrl->labels->distrib);
    printf("| %c | %2d | %70s |\n",(ctrl->plotstyle == ctrl->labels->xy?'*':' ')     ,2,ctrl->labels->xy);
    printf("| %c | %2d | %70s |\n",(ctrl->plotstyle == ctrl->labels->xyz?'*':' ')    ,3,ctrl->labels->xyz);
    printf("-----------------------------------------------------------------------------------\n");
    printf("| %c | %2d | %70s |\n",' ',4,"back");
    printf("-----------------------------------------------------------------------------------\n");    
    printf("choice : ");
  }while(scan_choice(&option) && option != 4);
  return 1;
}

int logfirst_menu(MENU_FN* menu_fct,menu_info* info){
  int option = -1;
  logFctrl* ctrl;

  WARNING((info->info1 == NULL,"logfirst_menu error 1 : info->info1 undefined\n"),0);
  ctrl = (logFctrl*)info->info1;

  do{
    info->option = option;
    (*menu_fct)(info);
    printf("------------------------------------------------------------------------------------------------------\n");
    printf("| %98s |\n","Before execution time load balancing log file options");
    printf("------------------------------------------------------------------------------------------------------\n");
    printf("| %2s | %20s | %70s |\n","","option","value");
    printf("------------------------------------------------------------------------------------------------------\n");
    printf("| %2d | %20s | %70s |\n",0,"Style",ctrl->plotstyle);
    printf("| %2d | %20s | %70s |\n",1,"Statistics output",ctrl->F_stats);
    printf("| %2d | %20s | %63s %6s |\n",2,"Plots output",ctrl->F_plot,ctrl->labels->ext[ctrl->plot_ext]);
    printf("| %2d | %20s | %70s |\n",3,"partition",ctrl->part);
    printf("| %2d | %20s | %70s |\n",4,"X values",ctrl->labels->label[ctrl->x]);
    if(ctrl->plotstyle == ctrl->labels->xy || ctrl->plotstyle == ctrl->labels->xyz)
      printf("| %2d | %20s | %70s |\n",5,"Y values",ctrl->labels->label[ctrl->y]);
    if(ctrl->plotstyle == ctrl->labels->xyz)
      printf("| %2d | %20s | %70s |\n",6,"Z values",ctrl->labels->label[ctrl->z]);      
    if(ctrl->plotstyle == ctrl->labels->distrib)      
      printf("| %2d | %20s | %70d |\n",7,"number of bars",ctrl->nb_bars);
    printf("| %2d | %20s | %70s |\n",8,"Group",(ctrl->group == BY_MATCHING ? "by matching file":"by coarsening method"));
    printf("------------------------------------------------------------------------------------------------------\n");
    printf("| %2d | %93s |\n",9,"Back");
    printf("| %2d | %93s |\n",10,"Run");
    printf("------------------------------------------------------------------------------------------------------\n");
    printf("choice : ");

  }while(scan_choice(&option) && option != 9);
  return 1;
}
